#ifndef __CLOUD_CONFIGURATION__
#define __CLOUD_CONFIGURATION__

#include <fstream>
#include "util.hpp"

#include "log_system/log_system.h"

namespace cloud
{
#define CONFIG_FILE "./conf/cloud.conf"

#define CONF_LOGGER "conf_logger"
    class Configuration
    {
    private:
        int _hot_time;
        int _server_port;
        std::string _compress_suffix;
        std::string _backup_dir;
        std::string _compress_dir;
        std::string _server_ip;
        std::string _information_file;
        std::string _download_prefix;


    private:
        Configuration() 
        {
            if(!ReadConfigFile())
            {
                exit(-1);
            }
        }

        bool ReadConfigFile()
        {
            std::unique_ptr<log_system::LoggerBuilder> llBuilder(new log_system::LocalLoggerBuilder());
            llBuilder->buildLoggerName(CONF_LOGGER);
            llBuilder->buildLoggerType(log_system::LoggerType::LOGGER_ASYNC);
            llBuilder->buildSink<log_system::StdoutSink>();
            llBuilder->buildSink<log_system::FileSink>("./log/conf_logger.txt");

            log_system::Logger::ptr logger = llBuilder->build();

            FileUtil conf_file_fu(CONFIG_FILE);

            if(!conf_file_fu.Exists())
            {
                // 若配置文件不存在，创建默认的配置文件
                logger->warnLog("加载配置文件时%s配置文件不存在", CONFIG_FILE);

                conf_file_fu.CreateParentDir();
                logger->infoLog("创建%s配置文件所在目录", CONFIG_FILE);

                Json::Value root;

                root["hot_time"]  = 2 * 24 * 60 * 60;
                root["server_port"] = 9090;
                root["server_ip"] = "192.168.15.10";
                root["compress_suffix"] = ".zstf";
                root["compress_dir"] = "./compress/";
                root["backup_dir"] = "./backup/";
                root["information_file"] = "./cloud.dat";
                root["download_prefix"] = "/download/";

                std::string content;
                JsonUtil::Serialize(root, &content);

                if(!conf_file_fu.SetContent(content))
                {
                    logger->fatalLog("创建%s默认配置文件失败", CONFIG_FILE);
                    return false;
                }
                logger->infoLog("创建%s默认配置文件成功", CONFIG_FILE);
            }

            std::string content;
            

            if(!conf_file_fu.GetContent(&content))
            {
                logger->fatalLog("%s配置信息读取失败", CONFIG_FILE);
                return false;
            }
            logger->infoLog("读取%s配置信息", CONFIG_FILE);

            Json::Value root;
            if(!JsonUtil::Unserialize(content, &root))
            {
                logger->fatalLog("%s配置信息反序列化失败", CONFIG_FILE);
                return false;
            }
            

            // 加载配置信息
            bool flag = true;
            Json::Value value;
            value = root["hot_time"];
            if(value.isNull())
            {
                logger->fatalLog("%s配置信息缺少hot_time项", CONFIG_FILE);
                flag = false;
            }
            _hot_time = value.asInt();

            value = root["server_port"];
            if(value.isNull())
            {
                logger->fatalLog("%s配置信息缺少server_port项", CONFIG_FILE);
                flag = false;
            }
            _server_port = value.asInt();


            value = root["server_ip"];
            if(value.isNull())
            {
                logger->fatalLog("%s配置信息缺少server_ip项", CONFIG_FILE);
                flag = false;
            }
            _server_ip = value.asString();

            value = root["compress_suffix"];
            if(value.isNull())
            {
                logger->fatalLog("%s配置信息缺少compress_suffix项", CONFIG_FILE);
                flag = false;
            }
            _compress_suffix = value.asString();

            value = root["compress_dir"];
            if(value.isNull())
            {
                logger->fatalLog("%s配置信息缺少compress_dir项", CONFIG_FILE);
                flag = false;
            }
            _compress_dir = value.asString();

            value = root["backup_dir"];
            if(value.isNull())
            {
                logger->fatalLog("%s配置信息缺少backup_dir项", CONFIG_FILE);
                flag = false;
            }
            _backup_dir = value.asString();

            value = root["information_file"];
            if(value.isNull())
            {
                logger->fatalLog("%s配置信息缺少information_file项", CONFIG_FILE);
                flag = false;
            }
            _information_file = value.asString();

            value = root["download_prefix"];
            if(value.isNull())
            {
                logger->fatalLog("%s配置信息缺少download_prefix项", CONFIG_FILE);
                flag = false;
            }
            _download_prefix = value.asString();

            if(!flag)    return false;
            // _hot_time = root["hot_time"].asInt();
            // _server_port = root["server_port"].asInt();
            // _server_ip = root["server_ip"].asString();
            // _compress_suffix = root["compress_suffix"].asString();
            // _compress_dir = root["compress_dir"].asString();
            // _backup_dir = root["backup_dir"].asString();
            // _information_file = root["information_file"].asString();
            // _download_prefix = root["download_prefix"].asString();

            logger->infoLog("%s配置信息读取完毕", CONFIG_FILE);
            return true;
        }

    public:
        static Configuration* GetInstance()
        {
            static Configuration instance;
            return &instance;
        }

        int GetHotTime()
        {
            return _hot_time;
        }

        int GetServerPort()
        {
            return _server_port;
        }

        std::string GetCompressSuffix()
        {
            return _compress_suffix;
        }

        std::string GetBackupDir()
        {
            return _backup_dir;
        }
        
        std::string GetCompressDir()
        {
            return _compress_dir;
        }

        std::string GetServerIp()
        {
            return _server_ip;
        }

        std::string GetInformationFile()
        {
            return _information_file;
        }

        std::string GetDownloadPrefix()
        {
            return _download_prefix;
        }

    };


}


#endif